Pesquisa — Desconto PIX + CrmBonus: fluxo atual e impacto do upsell
Data: 2026-05-15 Contexto: Task #193232 — Análise do fluxo de integração CRMBonus Fontes:
coezzion-service-checkout/src/coezzion-service-cart/src/coezzion-db-core/src/coezzion-db-link/src/
Seção 1 — Fluxo PIX + CrmBonus (comportamento atual, sem upsell)
Como o desconto PIX é configurado
O desconto PIX é um percentual por loja, armazenado em StoresPayment.PixDiscountPercentage (decimal(5,2), nullable). Não é um valor fixo — é calculado sobre cart.ItemsTotal no momento em que o cliente escolhe PIX.
// coezzion-db-core/src/Core.OrgDB/Entities/StorePaymentModel.cs, linha 60
public decimal? PixDiscountPercentage { get; set; }
Onde o desconto PIX é persistido
Dois lugares:
| Entidade | Campos | Quando é gravado |
|---|---|---|
PaymentsDataModel (tabela PaymentsData, banco zzlink) | PixDiscountPercentage, PixDiscountValue | Quando o cliente escolhe PIX (PixBraspagService.ApplyPixDiscount) |
CartModel (tabela Carts, banco core) | PixDiscountPercentage, PixDiscountValue | Após captura — via fila AWS_SQS_CHANGE_CART_VALUES |
Linha do tempo completa
[Vendedora cria cart com CrmBonus]
└─ cart.Total = ItemsTotal + Frete - CrmBonus.RescuedBonus
└─ cart.CrmBonus.Total = Total original (gravado uma vez, imutável)
[CreatePaymentCommandHandler — criação do pedido]
└─ baixa_bonus → CRM
valor_bruto = cart.Total ← SEM desconto PIX
bonus_resgatado = CrmBonus.RescuedBonus
[Cliente abre zzlink — GetCartInfo]
└─ Lê StoresPayment.PixDiscountPercentage
└─ Exibe simulação: TotalWhenPix = cart.Total - (ItemsTotal × %)
(apenas visual, cart.Total não é alterado aqui)
[Cliente escolhe PIX — PixBraspagService.CreateOrderBraspagAsync()]
└─ PixDiscountValue = round(ItemsTotal × PixDiscountPercentage / 100, 2)
└─ paymentData.Value -= PixDiscountValue ← valor real cobrado via PIX
└─ Persiste PixDiscountPercentage + PixDiscountValue em PaymentsData
[Cliente paga — PIX confirmado]
[PosCaptureService.ExecutePosCapture()]
├─ Passo 4: finaliza_compra → CRM
│ valor_bruto = cart.CrmBonus.Total ← valor congelado na criação, SEM desconto PIX
│ bonus_resgatado = CrmBonus.RescuedBonus
│
├─ Passo 5: IntegrationPdvEvent
│ PdvIntegrationValue = ItemsTotal - CrmBonus.RescuedBonus ← SEM desconto PIX
│ PixDiscountValue = calculado ← separado, para o PDV
│
└─ Passo 6: ExecutePaymentChangeEvent → fila SQS
└─ ValuesCartChangedEvent: Total + PixDiscountPercentage + PixDiscountValue
└─ CartService.Handle(UpdateCartValuesCommand)
└─ cart.Total atualizado com valor real pago (pós-PIX)
cart.PixDiscountPercentage e cart.PixDiscountValue gravados
Relação entre os dois descontos
O CalculateTotal() do CartModel não aplica desconto PIX — ele só deduz CrmBonus.RescuedBonus:
// coezzion-db-core/src/Core.OrgDB/Entities/CartModel.cs
public void CalculateTotal()
{
ItemsTotal = CartItems.Sum(p => p.CalculateTotal());
Total = ItemsTotal;
if (ShipmentValue is > 0) Total += ShipmentValue.Value;
if (CrmBonus is { RescuedBonus: > 0 })
{
Total -= CrmBonus.RescuedBonus.Value;
PdvIntegrationValue -= CrmBonus.RescuedBonus.Value;
}
// desconto PIX não está aqui
}
O desconto PIX é aplicado diretamente no paymentData.Value no momento da criação da ordem PIX — fora do ciclo de vida do cart.Total.
Conclusão da Seção 1
Os dois descontos operam em campos diferentes, em momentos diferentes, sem interferência mútua:
CrmBonus.RescuedBonusé deduzido docart.Totalna criação do pedido e enviado ao CRM comobonus_resgatado— fixo.PixDiscountValueé calculado no momento da escolha do PIX, aplicado nopaymentData.Value, e só chega aocart.Totalapós a captura via fila — posterior ao CRM.
O CRM nunca recebe o desconto PIX — nem no baixa_bonus nem no finaliza_compra. Isso é consistente e intencional no fluxo atual: o valor_bruto representa o valor do pedido antes de descontos de meio de pagamento.
Não há conflito hoje.
Seção 2 — Impacto do upsell no cenário combinado (PIX + CrmBonus + itens adicionados)
O que muda com upsell
Com a feature de upsell, o cliente pode adicionar itens ao carrinho após a criação do pedido (após baixa_bonus já ter sido executado). Isso altera cart.ItemsTotal e cart.Total, mas não altera cart.CrmBonus.Total nem CrmBonus.RescuedBonus — ambos são imutáveis.
Seja:
T0=cart.Totalno momento da criação do pedido (base dobaixa_bonus)ΔItem= valor do item adicionado via upsellB=CrmBonus.RescuedBonus(imutável)P%=PixDiscountPercentageda loja
Evolução dos valores ao longo do fluxo com upsell
| Momento | cart.Total | cart.ItemsTotal | cart.CrmBonus.Total | Desconto PIX calculado |
|---|---|---|---|---|
| Criação do pedido | T0 | T0 + B (aprox.) | T0 (congelado) | — |
| Após upsell | T0 + ΔItem | T0 + B + ΔItem (aprox.) | T0 (não muda) | — |
| Cliente escolhe PIX | T0 + ΔItem | T0 + B + ΔItem | T0 (não muda) | (T0 + B + ΔItem) × P% |
| Captura | — | — | — | efetivado |
finaliza_compra (passo 4) | T0 + ΔItem | — | T0 ← enviado ao CRM | já incluído na base do PIX |
| Cart atualizado via fila (passo 6) | T0 + ΔItem - PIX | — | T0 (não muda) | gravado no cart |
As três divergências acumuladas
Com upsell ativo, as chamadas ao CRM ficam assim:
baixa_bonus (criação do pedido — antes do upsell):
valor_bruto = T0 ← valor do pedido original, sem o item de upsell
bonus_resgatado = B
finaliza_compra (após captura — depois do upsell e do PIX):
valor_bruto = cart.CrmBonus.Total = T0 ← valor congelado, sem upsell, sem PIX
bonus_resgatado = B
Valor real pago pelo cliente:
valor real = T0 + ΔItem - B - (T0 + B + ΔItem) × P%
Resultado: o CRM processa a efetivação com valor_bruto = T0, enquanto o cliente pagou um valor diferente nas duas direções — maior (por causa do upsell) e menor (por causa do PIX). O CRM não vê nenhum dos dois ajustes.
Impacto no cálculo do desconto PIX com upsell
O desconto PIX é calculado sobre cart.ItemsTotal no momento em que o cliente escolhe PIX. Com upsell, esse ItemsTotal já inclui o item adicionado — então o upsell aumenta a base de cálculo do desconto PIX:
Sem upsell: PixDiscountValue = ItemsTotal_original × P%
Com upsell: PixDiscountValue = (ItemsTotal_original + ΔItem) × P%
O cliente recebe desconto PIX também sobre o item de upsell. Isso é provavelmente correto do ponto de vista de negócio, mas não há nada no fluxo atual que impeça ou sinalize essa situação.
Resumo dos riscos combinados
| Risco | Origem | Impacto no CRM |
|---|---|---|
valor_bruto do baixa_bonus não inclui o item de upsell | baixa_bonus usa cart.Total no momento da criação | CRM reservou bônus com valor menor que o pedido final |
valor_bruto do finaliza_compra não inclui upsell nem PIX | finaliza_compra usa cart.CrmBonus.Total congelado | CRM efetiva com valor diferente do valor real pago |
| Desconto PIX cresce com o upsell | base de cálculo é ItemsTotal no momento da escolha PIX | Desconto maior do que seria sem upsell — impacto na margem da loja |
Ponto crítico: o CRM valida valor_bruto entre as chamadas?
A questão central permanece sem resposta (ver Ponto 1 em task-193232-checkout-crm.md):
- o CRM rejeita
finaliza_comprase ovalor_brutofor diferente dobaixa_bonus? - No cenário combinado PIX + CrmBonus + upsell, a diferença entre os dois
valor_brutoé máxima — incluiΔIteme o tempo entre as chamadas é maior (upsell acontece entre as duas).